home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / TransSkel / Demos / C Demos / MultiSkel / MSkelHelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  7.0 KB  |  279 lines  |  [TEXT/KAHL]

  1. /*
  2.  * TransSkel multiple-window demonstration: Help module
  3.  * 
  4.  * This module handles a help window, in which text may be scrolled but
  5.  * not edited.  A TextEdit record is used to hold the text, though.
  6.  * 
  7.  * 21 Apr 88 Paul DuBois
  8.  * 29 Jan 89
  9.  * - Conversion for TransSkel 2.0.
  10.  * 12 Jan 91
  11.  * - Conversion for TransSkel 3.0.
  12.  */
  13.  
  14. # include    "TransSkel.h"
  15.  
  16. # include    "MultiSkel.h"
  17.  
  18.  
  19.  
  20. static TEHandle            teHelp;        /* handle to help window TextEdit record */
  21. static ControlHandle    helpScroll;    /* help window scroll bar */
  22. static short            helpLine;    /* line currently at top of window */
  23. static short            halfPage;    /* number of lines in half a window */
  24.  
  25.  
  26. /*
  27.  * Scroll to the correct position.  lDelta is the
  28.  * amount to CHANGE the current scroll setting by.
  29.  */
  30.  
  31. static void
  32. DoScroll (short lDelta)
  33. {
  34. short    newLine;
  35.  
  36.     newLine = helpLine + lDelta;
  37.     if (newLine < 0)
  38.         newLine = 0;
  39.     if (newLine > GetCtlMax (helpScroll))
  40.         newLine = GetCtlMax (helpScroll);
  41.     SetCtlValue (helpScroll, newLine);
  42.     lDelta = (helpLine - newLine ) * (**teHelp).lineHeight;
  43.     TEScroll (0, lDelta, teHelp);
  44.     helpLine = newLine;
  45. }
  46.  
  47.  
  48. /*
  49.  * Filter proc for tracking mousedown in scroll bar.  The part code
  50.  * of the part originally hit is stored as the control's reference
  51.  * value.
  52.  *
  53.  * The "void" had better be there!  Otherwise the compiler will treat
  54.  * it as an integer function, not a procedure.
  55.  */
  56.  
  57. static pascal void
  58. TrackScroll (ControlHandle theScroll, short partCode)
  59. {
  60. short            lDelta;
  61.  
  62.     if (partCode == GetCRefCon (theScroll))    /* still in same part? */
  63.     {
  64.         switch (partCode)
  65.         {
  66.             case inUpButton: lDelta = -1; break;
  67.             case inDownButton: lDelta = 1; break;
  68.             case inPageUp: lDelta = -halfPage; break;
  69.             case inPageDown: lDelta = halfPage; break;
  70.         }
  71.         DoScroll (lDelta);
  72.     }
  73. }
  74.  
  75.  
  76. /*
  77.  * Handle hits in scroll bar
  78.  */
  79.  
  80. static pascal void
  81. Mouse (Point pt, long t, short mods)
  82. {
  83. short    thePart;
  84.  
  85.         if ((thePart = TestControl (helpScroll, pt)) == inThumb)
  86.         {
  87.             (void) TrackControl (helpScroll, pt, nil);
  88.             DoScroll (GetCtlValue (helpScroll) - helpLine);
  89.         }
  90.         else if (thePart != 0)
  91.         {
  92.             SetCRefCon (helpScroll, (long) thePart);
  93.             (void) TrackControl (helpScroll, pt, TrackScroll);
  94.         }
  95. }
  96.  
  97.  
  98. /*
  99.  * Update help window.  The update event might be in response to a
  100.  * window resizing.  If so, resize the rects and recalc the linestarts
  101.  * of the text.  To resize the rects, only the right edge of the
  102.  * destRect need be changed (the bottom is not used, and the left and
  103.  * top should not be changed). The viewRect should be sized to the
  104.  * screen.  Pull text down if necessary to fill window.
  105.  */
  106.  
  107. static pascal void
  108. Update (Boolean resized)
  109. {
  110. Rect    r;
  111. short    visLines;
  112. short    lHeight;
  113. short    topLines;
  114. short    nLines;
  115. short    scrollLines;
  116.  
  117.     r = helpWind->portRect;
  118.     EraseRect (&r);
  119.     if (resized)
  120.     {
  121.         r.left += 4;
  122.         r.bottom -= 2;
  123.         r.top += 2;
  124.         r.right -= 19;
  125.         (**teHelp).destRect.right = r.right;
  126.         (**teHelp).viewRect = r;
  127.         TECalText (teHelp);
  128.         lHeight = (**teHelp).lineHeight;
  129.         nLines = (**teHelp).nLines;
  130.         visLines = (r.bottom - r.top) / lHeight;
  131.         halfPage = visLines / 2;
  132.         topLines = (r.top - (**teHelp).destRect.top) / lHeight;
  133.         scrollLines = visLines - (nLines - topLines);
  134.         if (scrollLines > 0 && topLines > 0)
  135.         {
  136.             if (scrollLines > topLines)
  137.                 scrollLines = topLines;
  138.             TEScroll (0, scrollLines * lHeight, teHelp);
  139.         }
  140.         scrollLines = nLines - visLines;
  141.         helpLine = (r.top - (**teHelp).destRect.top) / lHeight;
  142.  
  143.         /*
  144.          * Move and resize the scroll bar as well.  The ValidRect call is done
  145.          * because the HideControl adds the control bounds box to the update
  146.          * region - which would generate another update event!  Since everything
  147.          * gets redrawn below, the ValidRect is used to cancel the update.
  148.          */
  149.  
  150.         HideControl (helpScroll);
  151.         r = helpWind->portRect;
  152.         r.left = r.right - 15;
  153.         r.bottom -= 14;
  154.         --r.top;
  155.         ++r.right;
  156.         SizeControl (helpScroll, r.right - r.left, r.bottom - r.top);
  157.         MoveControl (helpScroll, r.left, r.top);
  158.         SetCtlMax (helpScroll, nLines - visLines < 0 ? 0 : nLines - visLines);
  159.         SetCtlValue (helpScroll, helpLine);
  160.         /*if (scrollLines <= 0)
  161.             HiliteControl (helpScroll, (scrollLines > 0 ? 0 : 255));*/
  162.         ShowControl (helpScroll);
  163.         /*if (GetCtlValue (helpScroll) > scrollLines)
  164.             DoScroll (GetCtlValue (helpScroll) - scrollLines);*/
  165.     }
  166.     DrawGrowBox (helpWind);
  167.     DrawControls (helpWind);    /* redraw scroll bar */
  168.     r = (**teHelp).viewRect;
  169.     TEUpdate (&r, teHelp);        /* redraw text display */
  170.     ValidRect (&helpWind->portRect);
  171. }
  172.  
  173.  
  174. /*
  175.  * When the window comes active, disable the Edit menu and highlight
  176.  * the scroll bar if there are any lines not visible in the content
  177.  * region.  When the window is deactivated, enable the Edit menu and
  178.  * un-highlight the scroll bar.
  179.  */
  180.  
  181. static pascal void
  182. Activate (Boolean active)
  183. {
  184.     DrawGrowBox (helpWind);
  185.     if (active)
  186.     {
  187.         DisableItem (editMenu, 0);
  188.         HiliteControl (helpScroll,
  189.                     (GetCtlMax (helpScroll) > 0 ? normalHilite : dimHilite));
  190.     }
  191.     else
  192.     {
  193.         EnableItem (editMenu, 0);
  194.         HiliteControl (helpScroll, dimHilite);
  195.     }
  196.     DrawMenuBar ();
  197. }
  198.  
  199.  
  200. static pascal void
  201. Clobber (void)
  202. {
  203.     TEDispose (teHelp);
  204.     DisposeControl (helpScroll);
  205.     DisposeWindow (helpWind);
  206. }
  207.  
  208.  
  209. void
  210. HelpWindInit (void)
  211. {
  212. Rect    r;
  213. Handle    textHandle;
  214. short    visLines;
  215. short    scrollLines;
  216.  
  217.     if (SkelQuery (skelQHasColorQD))
  218.         helpWind = GetNewCWindow (helpWindRes, nil, (WindowPtr) -1L);
  219.     else
  220.         helpWind = GetNewWindow (helpWindRes, nil, (WindowPtr) -1L);
  221.     if (helpWind == (WindowPtr) nil)
  222.         return;
  223.     (void) SkelWindow (helpWind,
  224.                 Mouse,        /* handle clicks in scrollbar */
  225.                 nil,        /* ignore keyclicks */
  226.                 Update,
  227.                 Activate,
  228.                 nil,        /* no close proc */
  229.                 Clobber,    /* disposal proc */
  230.                 nil,        /* no idle proc */
  231.                 false);
  232.  
  233.     TextFont (0);
  234.     TextSize (0);
  235.  
  236.     r = helpWind->portRect;
  237.     r.left += 4;
  238.     r.bottom -= 2;
  239.     r.top += 2;
  240.     r.right -= 19;
  241.     teHelp = TENew (&r, &r);
  242.     textHandle = GetResource ('TEXT', helpTextRes);    /* read help text */
  243.     HLock (textHandle);        /* lock it and insert into TERec */
  244.     TEInsert (*textHandle, GetHandleSize (textHandle), teHelp);
  245.     HUnlock (textHandle);
  246.     ReleaseResource (textHandle);    /* done with it, so goodbye */
  247.     /*
  248.      * Now figure out how many lines will fit in the window and how many
  249.      * will not.  Determine the number of lines in half a window for use
  250.      * in tracking clicks in the page up and page down regions of the
  251.      * scroll bar.  Then create the scroll bar .  Make sure the borders
  252.      * overlap the window frame and the frame of the grow box.
  253.      */
  254.     visLines = (r.bottom - r.top) / (**teHelp).lineHeight;
  255.     scrollLines = (**teHelp).nLines - visLines;
  256.     halfPage = visLines / 2;
  257.     helpLine = 0;
  258.     r = helpWind->portRect;
  259.     r.left = r.right - 15;
  260.     r.bottom -= 14;
  261.     --r.top;
  262.     ++r.right;
  263.     /*
  264.      * Build the scroll bar.  Don't need to bother testing whether to
  265.      * highlight it or not, since that will be done in response to the
  266.      * activate event.
  267.      */
  268.     helpScroll = NewControl (helpWind, &r, "\p", true,
  269.                     helpLine, 0, scrollLines, scrollBarProc, 0L);
  270.  
  271.     /*
  272.      * GetNewWindow generates an update event for entire portRect.
  273.      * Cancel it, since the everything has been drawn already,
  274.      * except for the grow box (which will be drawn in response
  275.      * to the activate event).
  276.      */
  277.     ValidRect (&helpWind->portRect);
  278. }
  279.